package com.chatsystem.listener;

import com.chatsystem.entity.User;
import com.chatsystem.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.messaging.SessionConnectedEvent;
import org.springframework.web.socket.messaging.SessionDisconnectEvent;

import java.util.Map;
import java.util.Optional;

/**
 * WebSocket事件监听器
 * 用于处理用户连接和断开连接事件，更新用户在线状态并广播
 * 
 * @author ChatSystem
 * @version 1.0.0
 */
@Component
@RequiredArgsConstructor
public class WebSocketEventListener {

    private final UserService userService;
    private final SimpMessagingTemplate messagingTemplate;

    /**
     * 监听WebSocket连接事件
     * 当用户连接到WebSocket时，更新其在线状态为ONLINE并通知其他用户
     * 
     * @param event SessionConnectedEvent
     */
    @EventListener
    public void handleWebSocketConnectListener(SessionConnectedEvent event) {
        SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor.wrap(event.getMessage());

        // 获取用户名，通常在认证成功后设置到sessionAttributes中
        String username = (String) headerAccessor.getSessionAttributes().get("username");

        if (username != null) {
            Optional<User> userOpt = userService.findByUsername(username);
            userOpt.ifPresent(user -> {
                // 更新用户在线状态为ONLINE
                boolean updated = userService.updateUserOnlineStatus(user.getId(), User.OnlineStatus.ONLINE);
                if (updated) {
                    // 广播用户上线消息
                    messagingTemplate.convertAndSend("/topic/public/status", 
                        Map.of("type", "USER_ACTIVE", 
                               "userId", user.getId(), 
                               "username", user.getUsername(),
                               "nickname", user.getNickname(),
                               "onlineStatus", User.OnlineStatus.ONLINE.name())); // 发送在线状态
                    System.out.println("用户 " + username + " (ID: " + user.getId() + ") 已上线，在线状态更新并广播。");
                } else {
                    System.err.println("用户 " + username + " (ID: " + user.getId() + ") 上线状态更新失败。");
                }
            });
        } else {
            System.err.println("WebSocket连接事件：无法从会话获取用户名。");
        }
    }

    /**
     * 监听WebSocket断开连接事件
     * 当用户断开WebSocket连接时，更新其在线状态为OFFLINE并通知其他用户
     * 
     * @param event SessionDisconnectEvent
     */
    @EventListener
    public void handleWebSocketDisconnectListener(SessionDisconnectEvent event) {
        SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor.wrap(event.getMessage());

        // 获取用户名
        String username = (String) headerAccessor.getSessionAttributes().get("username");

        if (username != null) {
            Optional<User> userOpt = userService.findByUsername(username);
            userOpt.ifPresent(user -> {
                // 更新用户在线状态为OFFLINE
                boolean updated = userService.updateUserOnlineStatus(user.getId(), User.OnlineStatus.OFFLINE);
                if (updated) {
                    // 广播用户下线消息
                    messagingTemplate.convertAndSend("/topic/public/status", 
                        Map.of("type", "USER_INACTIVE", 
                               "userId", user.getId(), 
                               "username", user.getUsername(),
                               "nickname", user.getNickname(),
                               "onlineStatus", User.OnlineStatus.OFFLINE.name())); // 发送在线状态
                    System.out.println("用户 " + username + " (ID: " + user.getId() + ") 已下线，在线状态更新并广播。");
                } else {
                    System.err.println("用户 " + username + " (ID: " + user.getId() + ") 下线状态更新失败。");
                }
            });
        } else {
            System.err.println("WebSocket断开连接事件：无法从会话获取用户名。");
        }
    }
} 